`ifndef CACHE_CONFIG_SV
`define CACHE_CONFIG_SV

`define ICACHE_INDEX 7
`define ICACHE_OFFSET 5
`define ICACHE_TAG (32 - `ICACHE_INDEX - `ICACHE_OFFSET)
`define ICACHE_INDEX_BUS `ICACHE_INDEX+`ICACHE_OFFSET -1 : `ICACHE_OFFSET
`define ICACHE_TAG_BUS 31 : 32 - `ICACHE_TAG
`define ICACHE_TAGV_BUS `ICACHE_TAG: 0
`define ICACHE_INDEX_SIZE (1 << `ICACHE_INDEX)
`define ICACHE_BANK_NUM 8
`define ICACHE_WAY_NUM 4

`define DCACHE_INDEX 7
`define DCACHE_OFFSET 5
`define DCACHE_TAG (32 - `DCACHE_INDEX - `DCACHE_OFFSET)
`define DCACHE_INDEX_BUS `DCACHE_INDEX+`DCACHE_OFFSET -1 : `DCACHE_OFFSET
`define DCACHE_TAG_BUS 31 : 32 - `DCACHE_TAG
`define DCACHE_TAGV_BUS `DCACHE_TAG: 0
`define DCACHE_INDEX_SIZE (1 << `DCACHE_INDEX)
`define DCACHE_WAY_NUM 4
`define DVICTIM_NUM 4

// write buffer
`define WRITE_BUFFER_LEN 8

// w: way number b: bank number 
// example: CACHE(n, 0, en): way0_bank0_en
`define CACHE_NAME(w, b, name) `concat3(way, ``w, `concat3(_bank, ``b, `concat(_, ``name)))
`define CACHE_ARGS(en, we, addr, din, dout) .clk(cpu_clk), .ena(en), .wea(we)\
	.addra(addr), .dina(din), .douta(dout)
	
`define CACHE_WAY_DEFINE(num, offset, index) \
	CacheWay #(\
		.OFFSET_SIZE(offset),\
		.INDEX_SIZE(index)\
	) way``num(\
		.cpu_clk(cpu_clk),\
		.cpu_rst_n(cpu_rst_n),\
		.index(ways[num].bank_index),\
		.tagv_index(ways[num].tagv_index),\
		.tagv_en(ways[num]. tagv_en),\
		.tagv_we(ways[num].tagv_we),\
		.tagv_wdata(ways[num].tagv_wdata),\
		.dirty_we(ways[num].dirty_we),\
		.dirty_wdata(ways[num].dirty_wdata),\
		.dirty_waddr(ways[num].dirty_waddr),\
		.dirty_raddr(ways[num].dirty_raddr),\
		.bank_en(ways[num].bank_en),\
		.bank_we(ways[num].bank_we),\
		.bank_wdata(ways[num].bank_wdata),\
		.bank_rdata(ways[num].bank_rdata),\
		.dirty_rdata(ways[num].dirty_rdata),\
		.tagv_rdata(ways[num].tagv_rdata)\
	);

`define VICTIM_CACHE_DEFINE(num)\
	DVictimCache#(.BUFFER_SIZE(8)) victim_cache``num(\
		.cpu_clk(cpu_clk),\
		.cpu_rst_n(cpu_rst_n),\
		.rd_req(rd_req),\
		.rd_addr(rd_addr),\
		.replace_en(replace_en),\
		.replace_miss_en(random_selector[num]),\
		.replace_addr(replace_addr),\
		.replace_data(replace_data),\
		.replace_hit(replace_hit_select[num]),\
		.hit(victim_hit[num]),\
		.ret_valid(victim_ret_valid[num]),\
		.ret_last(victim_ret_last[num]),\
		.ret_data(victim_ret_data[num])\
	);
`endif